package com.my.house.service;

import cn.hutool.core.util.DesensitizedUtil;
import com.my.house.FeeTypeEnum;
import com.my.house.common.config.AsyncConfig;
import com.my.house.domain.Building;
import com.my.house.domain.FeeRecord;
import com.my.house.domain.Room;
import com.my.house.domain.User;
import com.my.house.mapper.UserMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.my.house.vo.UserMainRespVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;

/**
 * 用户信息综合服务
 * @author yangll
 */
@Service
@RequiredArgsConstructor
public class UserService extends ServiceImpl<UserMapper, User> {
    private final BuildingService buildingService;
    private final RoomService roomService;
    private final ContractService contractService;
    private final FeeRecordService feeRecordService;
    private final AsyncConfig asyncConfig;

    public User getByMobile(String mobile) {
        return lambdaQuery().eq(User::getMobile, mobile).one();
    }

    public UserMainRespVO getUserMainInfo(User user, LocalDate start, LocalDate end) {
        assert user != null;
        UserMainRespVO vo = new UserMainRespVO();
        vo.setMobile(DesensitizedUtil.mobilePhone(user.getMobile()));
        vo.setUserName(DesensitizedUtil.chineseName(user.getUserName()));
        vo.setWaterPrice(user.getWaterPrice());
        vo.setElectricPrice(user.getElectricPrice());
        vo.setRentDay(user.getRentDay());

        Long userId = user.getId();
        Executor executor = asyncConfig.getAsyncExecutor();
        // 查询楼栋信息
        List<Building> buildings = buildingService.findByUserId(userId);
        vo.setBuildingTotal(buildings.size());
        if (vo.getBuildingTotal() > 0) {
            // 查询房间信息
            List<Long> buildingIdList = buildings.stream().map(Building::getId).toList();
            List<Room> rooms = roomService.findByBuildingIds(buildingIdList);
            vo.setRoomTotal(rooms.size());
            long count = rooms.stream().filter(Room::getEmptyStatus).count();
            vo.setEmptyRoomTotal((int) count);
            List<Long> roomIds = rooms.stream().map(Room::getId).toList();
            List<FeeRecord> feeRecords = feeRecordService.findByRoomIds(roomIds, start, end);
            // 设置本周期租房总收入
            feeRecords.stream().map(FeeRecord::getUseFee).reduce(BigDecimal::add).ifPresent(vo::setRentTotal);
            // 计算各种费用总收入
            Map<FeeTypeEnum, BigDecimal> typeFeeMap = feeRecords.stream().collect(Collectors.groupingBy(FeeRecord::getFeeType, Collectors.reducing(BigDecimal.ZERO, FeeRecord::getUseFee, BigDecimal::add)));
            for (Map.Entry<FeeTypeEnum, BigDecimal> entry : typeFeeMap.entrySet()) {
                FeeTypeEnum typeEnum = entry.getKey();
                if (typeEnum == FeeTypeEnum.RENT) {
                    vo.setRentTotal(entry.getValue());
                } else if (typeEnum == FeeTypeEnum.WATER) {
                    vo.setWaterTotal(entry.getValue());
                } else if (typeEnum == FeeTypeEnum.ELECTRIC) {
                    vo.setElectricTotal(entry.getValue());
                }
            }
        }
        return vo;
    }

    public boolean resetWatPriceByUserId(Long userId, BigDecimal price) {
        return lambdaUpdate().eq(User::getId, userId).set(User::getWaterPrice, price).update();
    }

    public boolean resetElePriceByUserId(Long userId, BigDecimal price) {
        return lambdaUpdate().eq(User::getId, userId).set(User::getElectricPrice, price).update();
    }

    public boolean resetRentDayByUserId(Long userId, Integer rentDay) {
        return lambdaUpdate().eq(User::getId, userId).set(User::getRentDay, rentDay).update();
    }
}